package com.dd.cloud.common.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.dd.cloud.common.annotate.Desensitized;
import com.dd.cloud.common.enums.SensitiveTypeEnum;
import com.dd.cloud.common.utils.DesensitizedUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Objects;


/**
* @Author: czg
* @Description: 脱敏注解字段自定义序列化
* @DateTime: 2022/9/21 17:44
* @Params: 
* @Return 
*/
@Slf4j
public class DesensitizedSerializer extends JsonSerializer<Object> {

    /**
    * @Author: czg
    * @Description: 自定义序列化
    * @DateTime: 2022/9/22 10:07
    * @Params: 
    * @Return 
    */
    @Override
    public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
        if (Objects.isNull(value)) {
            return;
        }
        //log.info("自定义注解序列化脱敏");
        JsonStreamContext outputContext = jsonGenerator.getOutputContext();
        // 获取当前class对象
        Class<?> clazz = outputContext.getCurrentValue().getClass();
        // 获取当前属性名
        String fieldName = outputContext.getCurrentName();
        // 获取当前属性的field
        Field field = FieldUtils.getDeclaredField(clazz, fieldName, true);
        // 获取当前属性的注解
        Desensitized annotation = field.getAnnotation(Desensitized.class);
        if (annotation == null) {
            jsonGenerator.writeObject(value);
            return;
        }
        String valueStr = (String) value;
        SensitiveTypeEnum type = annotation.type();
        Object des = desensitized(type, valueStr);
        log.info(value.toString());
        jsonGenerator.writeObject(des);
    }

    /**
     * 处理字段脱敏
     *
     * @param type
     * @param valueStr
     * @return
     */
    public Object desensitized(SensitiveTypeEnum type, String valueStr) {
        switch (type) {
            case CHINESE_NAME:
                return DesensitizedUtils.chineseName(valueStr);
            case ID_CARD:
                return DesensitizedUtils.idCardNum(valueStr);
            case FIXED_PHONE:
                return DesensitizedUtils.fixedPhone(valueStr);
            case MOBILE_PHONE:
                return DesensitizedUtils.mobilePhone(valueStr);
            case ADDRESS:
                return DesensitizedUtils.address(valueStr, 8);
            case EMAIL:
                return DesensitizedUtils.email(valueStr);
            case BANK_CARD:
                return DesensitizedUtils.bankCard(valueStr);
            case PASSWORD:
                return DesensitizedUtils.password(valueStr);
            case CARNUMBER:
                return DesensitizedUtils.carNumber(valueStr);
            default:
        }
        return valueStr;
    }
}
